% MATLAB References 
% https://www.mathworks.com/help/control/ug/build-app-with-interactive-plot-updates.html?requestedDomain=www.mathworks.com
% https://www.mathworks.com/help/control/ref/updatesystem.html
% http://stackoverflow.com/questions/15975758/matlab-simple-slider-on-a-figure
% uicontrol.Positon ([left bottom width height])
% https://www.mathworks.com/matlabcentral/newsreader/view_thread/323414
% http://stackoverflow.com/questions/21681167/continuously-update-slider-in-matlab

% OCTAVE References
% https://wiki.octave.org/Uicontrols
% https://octave.org/doc/v5.2.0/Uipanel-Properties.html#Uipanel-Properties
% https://stackoverflow.com/questions/43519040/how-to-code-a-slider-in-octave-to-have-interactive-plot
% uicontrol position notes: [x, y, l, w]
%   -> x | relative to the left side of parent object [0 (left) - 1(right)]
%   -> y | relative to the bottom side of the parent object [0 (bottom) - 1 (top)]
%   -> l | length of slider (follows same relative positioning as x)
%   -> w | width of slider (follows same relative positioning as y)

close all
clear h

function [] = updatePlot(obj)
%function [] = updatePlot(obj)
h = guidata(obj);
dutyCycle = get(h.dutyControl, "value"); 
Rload = get(h.loadControl, "value");
L = get(h.inductorControl, "value");
Vout = get(h.voltageControl, "value");
freq = get(h.frequencyControl, "value");

Iout = Vout / Rload;
Vin = Vout*(1-dutyCycle);
Iin = (Vout*Iout)./Vin;
dutyVector = linspace(0.001, 0.999, 1000);

I_LB = (((Vout).*(1-dutyVector).*dutyVector)./(L*freq));
I_OB = ((((Vout).*((1-dutyVector).^2).*dutyVector)./(2*L*freq)));

cla
hold on;
plot(dutyVector, I_LB, "b", "linewidth", 4);
plot(dutyVector, I_OB, "r", "linewidth", 4);
plot(dutyCycle, Iin, "go", "markersize", 12);
plot(dutyCycle, Iout, "ko", "markersize", 12);
hold off;


set(h.dutyCycleLabel, "string", sprintf("Duty Cycle => %.3f%%", dutyCycle*100));
set(h.loadLabel, "string", sprintf("Resistive Load => %3.3f Ohm", Rload));
set(h.inductanceLabel, "string", sprintf("Inductance => %g H", L));
set(h.voltageLabel, "string", sprintf("Output Voltage => %3.3f V", Vout));
set(h.frequencyLabel, "string", sprintf("Frequency => %5.3f Hz", freq));

endfunction

%% Configuration Values
initialDutyCycle = 0.50;
dutyCycleBounds = [0.001, 0.999];

initialRLoad = 20;
RLoadBounds = [0, 50];

initialVout = 10;
VoutBounds = [0, 50];

initialInductance = 100e-6;
inductanceBounds = [100e-9, 100e-4];

initialFreq = 50e3;
freqBounds = [20e3, 100e3];

h.DCM_CCM = figure(
    "name", "DCM / CCM Visual Demonstration",
    "menubar","none",
    "position", [0, 0, 1080, 720], 
    "color", get(0, "defaultuicontrolbackgroundcolor"));
    
h.controlPanel = uipanel(
    "parent", h.DCM_CCM,
    "units", "normalized",
    "title", "Control",
    "fontSize", 12,
    "position", [0.010, 0.010, 0.290, 0.990],
    "backgroundcolor", get(0, "defaultuicontrolbackgroundcolor"));
    
h.graphPanel = uipanel(
    "parent", h.DCM_CCM,
    "units", "normalized",
    "title", "Graph",
    "fontSize", 12,
    "position", [0.310, 0.010, 0.990, 0.990],
    "backgroundcolor", get(0, "defaultuicontrolbackgroundcolor"));

    
h.ax = axes(
    "parent", h.graphPanel,
    "units", "normalized",
    "position", [0.075, 0.250, 0.60, 0.60],
    "fontsize", 16);
    
titleObj = title("Average Inductor Current vs Duty Cycle [Boost Converter]", 
    "fontsize", 24);
xlabelObj = xlabel("Duty Cycle [%]", 
    "fontsize", 24);    
ylabelObj = ylabel("Average Inductor Current [A]", 
    "fontsize", 24);

h.dutyControl = uicontrol(
    "parent", h.controlPanel,
    "style", "slider",
    "units", "normalized",
    "position", [0.0250, 0.90, 0.95, 0.030],
    "callback", @updatePlot,  
    "value", initialDutyCycle,    
    "min", dutyCycleBounds(1),
    "max", dutyCycleBounds(2));

h.dutyCycleLabel = uicontrol(
    "parent", h.controlPanel,
    "style", "text",
    "fontSize", 12,
    "units", "normalized",
    "horizontalalignment", "center",
    "position", [0.0250, 0.9350, 0.950, 0.030],
    "string", "Duty Cycle");

h.loadControl = uicontrol(
    "parent", h.controlPanel,
    "style", "slider",
    "units", "normalized",
    "position", [0.0250, 0.70, 0.950, 0.030],
    "callback", @updatePlot,
    "value", initialRLoad,
    "min", RLoadBounds(1), 
    "max", RLoadBounds(2));
    
h.loadLabel = uicontrol(
    "parent", h.controlPanel,
    "style", "text",
    "units", "normalized",
    "fontSize", 12,
    "position", [0.0250, 0.7350, 0.950, 0.030],
    "string", "Resistive Load");    

h.voltageControl = uicontrol(
    "parent", h.controlPanel,
    "style", "slider",
    "units", "normalized",
    "position", [0.0250, 0.50, 0.950, 0.030],
    "callback", @updatePlot,
    "value", initialVout,
    "min", VoutBounds(1),
    "max", VoutBounds(2));
    
h.voltageLabel = uicontrol(
    "parent", h.controlPanel,
    "style", "text",
    "units", "normalized",
    "fontSize", 12,
    "position", [0.0250, 0.5350, 0.950, 0.030],
    "string", "Output Voltage");     

h.inductorControl = uicontrol(
    "parent", h.controlPanel,
    "style", "slider",
    "units", "normalized",
    "position", [0.0250, 0.30, 0.950, 0.030],
    "callback", @updatePlot,
    "value", initialInductance,
    "min", inductanceBounds(1), 
    "max", inductanceBounds(2));
    
h.inductanceLabel = uicontrol(
    "parent", h.controlPanel,
    "style", "text",
    "units", "normalized",
    "fontSize", 12,
    "position", [0.0250, 0.3350, 0.950, 0.030],
    "string", "Inductance");     

h.frequencyControl = uicontrol(
    "parent", h.controlPanel,
    "style", "slider",
    "units", "normalized",
    "position", [0.0250, 0.10, 0.950, 0.030],
    "callback", @updatePlot,
    "value", initialFreq,
    "min", freqBounds(1),
    "max", freqBounds(2));
    
h.frequencyLabel = uicontrol(
    "parent", h.controlPanel,
    "style", "text",
    "units", "normalized",
    "fontSize", 12,
    "position", [0.0250, 0.1350, 0.950, 0.030],
    "string", "Frequency");
    
guidata(gcf, h)
updatePlot(gcf);
